Rails 5.1版本中,其中有一個的重點就是 form_with。在Rails 5.1之前,有兩種表格,一個是 form_tag,一個是 form_for,兩者有些微差異。在之前,如果表格的對象有Model,則用 form_for, Rails 會利用Model 的屬性來新增或更新 Model 所產生的資料;若沒有 Model 實體時,form_tag 則使用傳入連結的 action 進行表單傳送。
Rails 5.1之後,將 form_for 和 form_with 兩者的功能融合成為 form_with 是因為 form_tag 和 form_for 這兩個提供的功能,其實有很多是重複的,所以被加以整合,再者有些 helpler 有效能上的問題,因此便有了form_with這個新方法。
#users_controller.rb
#@user = User.new
<%= form_with model: @user do |form| %>
<%= form.label :name %>
<%= form.text_field :name %>
<%= form.submit %>
<% end %>
<%= form_with url: new_user_path do |form| %>
<%= form.label :name %>
<%= form.text_field :name %>
<%= form.submit %>
<% end %>
有了這個屬性之後,表單會透過 Ajax 的方式提交,而不是瀏覽器平常的提交機制,若要設定不讓Ajax的方式提交,則要另外加上 local: true。
#users_controller.rb
#@user = User.new
<%= form_with model: @user, local: true do |form| %>
<%= form.label :name %>
<%= form.text_field :name %>
<%= form.submit %>
<% end %>
form_for 或 for_tag 要設定 html 屬性的話需要加上 html: {屬性}
<%= form_for @user, html: { id: “user-id”} do |form| %>
form_with 則是直接寫屬性
<%= form_for @user, id: “user-id” do |form| %>
目前官方推薦的方法是使用 form_with 來製作表單,因為 form_with 整合了 form_for 跟 form_tag 這兩種做法,也對效能做了優化, 而且form_with 可以用 url 後面來帶一個真正的網址但是 form_for 不行,另外 form_with 預設是用非同步的方式送出表單,如果要關掉這個設定要另外加個 local:true 就是剛剛提到的透過 Ajax 方式提交表單,但是 form_for 則預設是同步的方式送出。
最後要注意的是使用的 gem 有沒有支援,例如 simple form 就不支援 form_with,使用上除了這點要稍微注意以外,其他的個人感覺都是 Z>B。